#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "script_expression.h"
#include "script.h"
#include "script_debug.h"
#include "script_var.h"

int judge(exp_node_t *value)
{
	exp_node_type_e type;
	int num;
	char *str;
	get_exp_node_value(value,&type,&str,&num,NULL);
	int flag = 0;

	if(type == EXP_NODE_TYPE_CONST_INT && num != 0){
		flag = 1;
	}else if(type == EXP_NODE_TYPE_CONST_TRUE){
		flag = 1;
	}else if(type == EXP_NODE_TYPE_VAR){
		exp_var_t *var = exp_var_point_take(value->var);
		if(var){
			if(var->type != EXP_VAR_TYPE_FALSE && var->type != EXP_VAR_TYPE_NONE){
				flag = 1;
			}
		}
	}

	return flag;

}

static exp_node_t *plus(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		SCRIPT_DEBUG_WARN( "script cal plus param is NULL\n");
		return NULL;
	}

	exp_node_type_e left_type, right_type;
	int left_int, right_int;
	char *left_str, *right_str;
	double left_d, right_d;

	get_exp_node_value(left, &left_type, &left_str, &left_int,&left_d);
	get_exp_node_value(right, &right_type, &right_str, &right_int,&right_d);

	exp_node_t *result = script_calloc(1, sizeof(exp_node_t));


	if(left_type == EXP_NODE_TYPE_CONST_INT){
		if(right_type == EXP_NODE_TYPE_CONST_INT){
			result->type = EXP_NODE_TYPE_CONST_INT;
			result->number = left_int + right_int;
		}else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_int + right_d;
		}else if(right_type == EXP_NODE_TYPE_CONST_STRING){
			result->type = EXP_NODE_TYPE_CONST_STRING;
			result->string = script_calloc(1, strlen(right_str) + 16);
			sprintf(result->string, "%d%s", left_int, right_str);
		}
	}else if(left_type == EXP_NODE_TYPE_CONST_DOUBLE){
		if(right_type == EXP_NODE_TYPE_CONST_INT){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_d + right_int;
		} else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_d + right_d;
		} else if(right_type == EXP_NODE_TYPE_CONST_STRING){
			result->type = EXP_NODE_TYPE_CONST_STRING;
			result->string = script_calloc(1, strlen(right_str) + 64);
			sprintf(result->string, "%f%s", left_d, right_str);
		}
	}else if (left_type == EXP_NODE_TYPE_CONST_STRING) {
		char *buf = exp_node_to_string(right);
		int len = strlen(left_str) + strlen(buf) + 64;
		result->type = EXP_NODE_TYPE_CONST_STRING;
		result->string = script_calloc(1,len);
		sprintf(result->string,"%s%s",left_str,buf);
		script_free(buf);
	}
	return result;
}

static exp_node_t *subtraction(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type, right_type;
	int left_int, right_int;
	char *left_str, *right_str;
	double left_d, right_d;

	get_exp_node_value(left, &left_type, &left_str, &left_int,&left_d);
	get_exp_node_value(right, &right_type, &right_str, &right_int,&right_d);

	exp_node_t *result = script_calloc(1, sizeof(exp_node_t));

	if(left_type == EXP_NODE_TYPE_CONST_INT){
		if(right_type == EXP_NODE_TYPE_CONST_INT){
			result->type = EXP_NODE_TYPE_CONST_INT;
			result->number = left_int - right_int;
		}else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_int - right_d;
		}
	}else if(left_type == EXP_NODE_TYPE_CONST_DOUBLE){
		if(right_type == EXP_NODE_TYPE_CONST_INT){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_d - right_int;
		} else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_d - right_d;
		}
	}
	return result;
}

static exp_node_t *multiply(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type, right_type;
	int left_int, right_int;
	char *left_str, *right_str;
	double left_d, right_d;

	get_exp_node_value(left, &left_type, &left_str, &left_int,&left_d);
	get_exp_node_value(right, &right_type, &right_str, &right_int,&right_d);

	exp_node_t *result = script_calloc(1, sizeof(exp_node_t));

	if(left_type == EXP_NODE_TYPE_CONST_INT){
		if(right_type == EXP_NODE_TYPE_CONST_INT){
			result->type = EXP_NODE_TYPE_CONST_INT;
			result->number = left_int * right_int;
		}else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_int * right_d;
		}
	}else if(left_type == EXP_NODE_TYPE_CONST_DOUBLE){
		if(right_type == EXP_NODE_TYPE_CONST_INT){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_d * right_int;
		} else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_d * right_d;
		}
	}

	return result;
}

static exp_node_t *division(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type, right_type;
	int left_int, right_int;
	char *left_str, *right_str;
	double left_d, right_d;

	get_exp_node_value(left, &left_type, &left_str, &left_int,&left_d);
	get_exp_node_value(right, &right_type, &right_str, &right_int,&right_d);

	exp_node_t *result = script_calloc(1, sizeof(exp_node_t));

	if(left_type == EXP_NODE_TYPE_CONST_INT){
		if(right_type == EXP_NODE_TYPE_CONST_INT){
			result->type = EXP_NODE_TYPE_CONST_INT;
			result->number = left_int / right_int;
		}else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_int / right_d;
		}
	}else if(left_type == EXP_NODE_TYPE_CONST_DOUBLE){
		if(right_type == EXP_NODE_TYPE_CONST_INT){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_d / right_int;
		} else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE){
			result->type = EXP_NODE_TYPE_CONST_DOUBLE;
			result->d = left_d / right_d;
		}
	}

	return result;
}
static exp_node_t *remainder(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type, right_type;
	int left_int, right_int;
	char *left_str, *right_str;
	double left_d, right_d;

	get_exp_node_value(left, &left_type, &left_str, &left_int,&left_d);
	get_exp_node_value(right, &right_type, &right_str, &right_int,&right_d);

	exp_node_t *result = script_calloc(1, sizeof(exp_node_t));

	if(left_type == EXP_NODE_TYPE_CONST_INT && right_type == EXP_NODE_TYPE_CONST_INT){
		result->type = EXP_NODE_TYPE_CONST_INT;
		result->number = left_int % right_int;
	}

	return result;
}

exp_node_t *refer(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}


	if (left->type != EXP_NODE_TYPE_VAR ) {
		return NULL;
	}

	if(left->var->type == EXP_VAR_TYPE_C_VAR){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	if(right->type != EXP_NODE_TYPE_VAR){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	exp_var_t *left_var = left->var;
	switch(left_var->type){
		case EXP_VAR_TYPE_STRUCT:
		case EXP_VAR_TYPE_POINT:
			exp_var_destroy(left_var->var);
			left_var->var = NULL;
			break;
		case EXP_VAR_TYPE_ARRAY:
			exp_array_destroy(left_var->array);
			left_var->array = NULL;
			break;
		case EXP_VAR_TYPE_STRING:
			if(left_var->str){
				script_free(left_var->str);
				left_var->str = NULL;
			}
			break;
		case EXP_VAR_TYPE_STRUCT_MEM:
		{
			exp_var_t *var = exp_var_parse(left_var->name,NULL);
			exp_var_struct_add(left_var->var,var);
			left_var = var;
		} break;
		default:
			break;
	}

	exp_var_t *right_var = exp_var_point_take(right->var);
	left_var->type = EXP_VAR_TYPE_POINT;
	left_var->var = exp_var_refer(right_var);

	return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);

}

exp_node_t *evaluation(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type, right_type;
	int left_int, right_int;
	char *left_str, *right_str;

	if (left->type != EXP_NODE_TYPE_VAR ) {
		return NULL;
	}

	if(left->var && left->var->type == EXP_VAR_TYPE_C_VAR){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	double left_d, right_d;

	get_exp_node_value(left, &left_type, &left_str, &left_int,&left_d);
	get_exp_node_value(right, &right_type, &right_str, &right_int,&right_d);


	exp_node_t *result = script_calloc(1, sizeof(exp_node_t));
	result->type = EXP_NODE_TYPE_CONST_NULL;


	exp_var_t *left_var = exp_var_point_take(left->var);

	if(left_var->type == EXP_VAR_TYPE_STRUCT){
		exp_object_destroy(left_var->object);
		left_var->object = NULL;
	}else if(left_var->type == EXP_VAR_TYPE_ARRAY){
		exp_array_destroy(left_var->array);
		left_var->array = NULL;
	}else if(left_var->type == EXP_VAR_TYPE_STRING){
		if(left_var->str){
			script_free(left_var->str);
			left_var->str = NULL;
		}
	}else if(left_var->type == EXP_VAR_TYPE_STRUCT_MEM){
		exp_var_t *var = exp_var_parse(left_var->name,NULL);
		exp_var_struct_add(left_var->var,var);
		left_var = var;

		// 指针变量需要重新指向新创建的变量
		if(left->var->type == EXP_VAR_TYPE_POINT){ 
			exp_var_destroy(left->var->var);
			left->var->var = exp_var_refer(var);
		}
	}

	left_var->type = EXP_VAR_TYPE_NONE;
	left_var->value = 0;

	if (right_type == EXP_NODE_TYPE_CONST_INT) {
		result->type = EXP_NODE_TYPE_CONST_INT;
		result->number = right_int;
		left_var->type = EXP_VAR_TYPE_INT;
		left_var->value = right_int;
	} else if(right_type == EXP_NODE_TYPE_CONST_DOUBLE) {
		result->type = EXP_NODE_TYPE_CONST_DOUBLE;
		result->d = right_d;
		left_var->type = EXP_VAR_TYPE_DOUBLE;
		left_var->number = right_d;
	} else if(right_type == EXP_NODE_TYPE_CONST_STRING) {
		result->type = EXP_NODE_TYPE_CONST_STRING;
		if(right_str){
			result->string = script_calloc(1, strlen(right_str) + 1);
			strcpy(result->string, right_str);
		}

		left_var->type = EXP_VAR_TYPE_STRING;
		left_var->str = script_calloc(1, strlen(right_str) + 1);
		strcpy(left_var->str, right_str);
	} else if(right_type == EXP_NODE_TYPE_VAR) {
		exp_var_t *right_var = exp_var_point_take(right->var);
		left_var->type = right_var->type;
		if(right_var->type == EXP_VAR_TYPE_STRUCT){
			left_var->object = exp_object_copy(right_var->object);
		}else if(right_var->type == EXP_VAR_TYPE_ARRAY){
			int i;
			left_var->array = exp_array_create();
			if(right_var->array){
				for(i = 0; i < right_var->array->len; i++){
					exp_var_t *sub = right_var->array->p[i];
					exp_array_add(left_var->array,exp_var_copy_to_new(sub));
				}
			}
		}else if(right_var->type == EXP_VAR_TYPE_FUNCTION){
			//left_var->func = right_var->func;
			left_var->type = EXP_VAR_TYPE_POINT;
			left_var->var = exp_var_refer(right_var);
		}
	} else if(right_type == EXP_NODE_TYPE_CONST_FALSE) {
		left_var->type = EXP_VAR_TYPE_FALSE;
	} else if(right_type == EXP_NODE_TYPE_CONST_TRUE) {
		left_var->type = EXP_VAR_TYPE_TRUE;
	} else {
		result->type = EXP_NODE_TYPE_CONST_NULL;
		left_var->type = EXP_VAR_TYPE_NONE;
	}

	return result;
}

exp_node_t *plus_evaluation(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	if (left->type != EXP_NODE_TYPE_VAR ) {
		return NULL;
	}

	if(left->var->type == EXP_VAR_TYPE_C_VAR){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}


	exp_node_t *value = plus(left,right);
	if(value == NULL){
		return NULL;
	}

	exp_node_t *result = evaluation(left,value);

	exp_node_destroy(value);

	return result;
}

exp_node_t *sub_evaluation(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	if (left->type != EXP_NODE_TYPE_VAR ) {
		return NULL;
	}

	if(left->var->type == EXP_VAR_TYPE_C_VAR){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}


	exp_node_t *value = subtraction(left,right);
	if(value == NULL){
		return NULL;
	}

	exp_node_t *result = evaluation(left,value);

	exp_node_destroy(value);

	return result;
}

static exp_node_t *equal(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type, right_type;
	int left_int, right_int;
	char *left_str, *right_str;
	double left_d, right_d;

	get_exp_node_value(left, &left_type, &left_str, &left_int,&left_d);
	get_exp_node_value(right, &right_type, &right_str, &right_int,&right_d);

	exp_node_t *result = script_calloc(1, sizeof(exp_node_t));
	result->type = EXP_NODE_TYPE_CONST_TRUE;



	if (left_type != right_type) {
		result->type = EXP_NODE_TYPE_CONST_FALSE;
	} else if (left_type == EXP_NODE_TYPE_CONST_INT) {
		if (left_int != right_int) {
			result->type = EXP_NODE_TYPE_CONST_FALSE;
		}
	} else if (left_type == EXP_NODE_TYPE_CONST_DOUBLE) {
		if (left_d != right_d) {
			result->type = EXP_NODE_TYPE_CONST_FALSE;
		}
	} else if (left_type == EXP_NODE_TYPE_CONST_STRING) {
		if (strcmp(left_str, right_str) != 0) {
			result->type = EXP_NODE_TYPE_CONST_FALSE;
		}
	} else if(left_type == EXP_NODE_TYPE_VAR){
		exp_var_t *left_var = exp_var_point_take(left->var);
		exp_var_t *right_var = exp_var_point_take(right->var);
		if(left_var->type != right_var->type){
			result->type = EXP_NODE_TYPE_CONST_FALSE;
		}else if(left_var->type == EXP_VAR_TYPE_ARRAY ||
				left_var->type == EXP_VAR_TYPE_STRUCT){
			result->type = EXP_NODE_TYPE_CONST_FALSE;
		}
	} else if(left_type == EXP_NODE_TYPE_CONST_NULL || left_type == EXP_NODE_TYPE_CONST_FALSE ||
			left_type == EXP_NODE_TYPE_CONST_TRUE){
		result->type = EXP_NODE_TYPE_CONST_TRUE;
	} else {
		result->type = EXP_NODE_TYPE_CONST_FALSE;
	}

	return result;
}

static exp_node_t *unequal(exp_node_t *left, exp_node_t *right)
{
	exp_node_t *result = equal(left, right);
	if (result) {
		if(result->type == EXP_NODE_TYPE_CONST_TRUE){
			result->type = EXP_NODE_TYPE_CONST_FALSE;
		}else{
			result->type = EXP_NODE_TYPE_CONST_TRUE;
		}
	}
	return result;
}

static exp_node_t *compare(exp_node_t *left, exp_node_t *right,operator_type_e type)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type, right_type;
	int left_int, right_int;
	char *left_str, *right_str;
	double left_d, right_d;

	get_exp_node_value(left, &left_type, &left_str, &left_int,&left_d);
	get_exp_node_value(right, &right_type, &right_str, &right_int,&right_d);

	exp_node_t *result = script_calloc(1, sizeof(exp_node_t));
	result->type = EXP_NODE_TYPE_CONST_FALSE;



	if (left_type != right_type) {
		SCRIPT_DEBUG_ERR("compare value error!11");
		exp_node_destroy(result);
		return exp_node_create(EXP_NODE_TYPE_ERR,NULL);
	} else if (left_type == EXP_NODE_TYPE_CONST_INT) {
		if ( (type == OPERTOR_TYPE_GREATER && left_int > right_int) ||
			 (type == OPERTOR_TYPE_GREATER_EQUAL && left_int >= right_int) ||
			 (type == OPERTOR_TYPE_LESS && left_int < right_int) ||
			 (type == OPERTOR_TYPE_LESS_EQUAL && left_int <= right_int) ){

			result->type = EXP_NODE_TYPE_CONST_TRUE;
		}
	} else if (left_type == EXP_NODE_TYPE_CONST_DOUBLE) {
		if ( (type == OPERTOR_TYPE_GREATER && left_d > right_d) ||
			(type == OPERTOR_TYPE_GREATER_EQUAL && left_d >=right_d) ||
			(type == OPERTOR_TYPE_LESS && left_d < right_d) ||
			(type == OPERTOR_TYPE_LESS_EQUAL && left_d <=right_d) ){
			result->type = EXP_NODE_TYPE_CONST_TRUE;
		}
	} else if (left_type == EXP_NODE_TYPE_CONST_STRING) {
		if ( (type == OPERTOR_TYPE_GREATER && strcmp(left_str, right_str) > 0) ||
			(type == OPERTOR_TYPE_GREATER_EQUAL && strcmp(left_str, right_str) >= 0) ||
			(type == OPERTOR_TYPE_LESS && strcmp(left_str, right_str) < 0) ||
			(type == OPERTOR_TYPE_LESS_EQUAL && strcmp(left_str, right_str) <= 0) ){
			result->type = EXP_NODE_TYPE_CONST_TRUE;
		}
	} else if(left_type == EXP_NODE_TYPE_VAR){
		exp_var_t *left_var = exp_var_point_take(left->var);
		exp_var_t *right_var = exp_var_point_take(right->var);
		if(left_var->type != right_var->type){
			SCRIPT_DEBUG_ERR("compare value error!");
			exp_node_destroy(result);
			return exp_node_create(EXP_NODE_TYPE_ERR,NULL);
		}else if(left_var->type == EXP_VAR_TYPE_ARRAY ||
				left_var->type == EXP_VAR_TYPE_STRUCT){
			SCRIPT_DEBUG_ERR("compare value error!");
			exp_node_destroy(result);
			return exp_node_create(EXP_NODE_TYPE_ERR,NULL);
		}
	}

	return result;
}

static exp_node_t *greater(exp_node_t *left, exp_node_t *right)
{
	return compare(left,right,OPERTOR_TYPE_GREATER);
}

static exp_node_t *less(exp_node_t *left, exp_node_t *right)
{
	return compare(left,right,OPERTOR_TYPE_LESS);
}

static exp_node_t *greater_equal(exp_node_t *left, exp_node_t *right)
{
	return compare(left,right,OPERTOR_TYPE_GREATER_EQUAL);
}

static exp_node_t *less_equal(exp_node_t *left, exp_node_t *right)
{
	return compare(left,right,OPERTOR_TYPE_LESS_EQUAL);
}

static exp_node_t *json_dot(exp_node_t *left, exp_node_t *right)
{
	exp_node_t *result;
	exp_node_type_e right_type;
	int right_int;
	char *right_str;

	if (left == NULL || right == NULL) {
		SCRIPT_DEBUG_ERR( "json dot left is NULL or right is NULL");
		return NULL;
	}

	if(left->type != EXP_NODE_TYPE_VAR){
		SCRIPT_DEBUG_WARN("left type invalid!");
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}
	
	exp_var_t *left_var = exp_var_point_take(left->var);
	if(left_var->type != EXP_VAR_TYPE_STRUCT){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,0);
	}
	get_exp_node_value(right, &right_type, &right_str, &right_int,NULL);

	if(right_type != EXP_NODE_TYPE_CONST_STRING){
		SCRIPT_DEBUG_ERR("right type invalid!");
		return NULL;
	}

	exp_var_t *var = exp_var_struct_get_var(left_var,right_str);
	result = exp_node_create(EXP_NODE_TYPE_VAR,NULL);
	if(var == NULL){
		//var = exp_var_parse(right_str,NULL);
		//printf("left_var name:%s\n",left_var->name);
		//exp_var_struct_add(left_var,var);
		var = exp_var_create(right_str);
		var->type = EXP_VAR_TYPE_STRUCT_MEM;
		var->var = exp_var_refer(left_var);
		result->var = var;
	}else{
		result->var = exp_var_refer(var);
	}

	return result;
}
static exp_node_t *bracket(exp_node_t *left, exp_node_t *right)
{
	exp_node_t *result;
	exp_node_type_e right_type;
	int right_int;
	char *right_str;

	if (left == NULL || right == NULL) {
		SCRIPT_DEBUG_ERR("struct dot left is NULL or right is NULL");
		return NULL;
	}

	if(left->type != EXP_NODE_TYPE_VAR){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	get_exp_node_value(right, &right_type, &right_str, &right_int,NULL);

	if(right_type != EXP_NODE_TYPE_CONST_INT && right_type != EXP_NODE_TYPE_CONST_STRING){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	exp_var_t *var = left->var;
	while(var && var->type == EXP_VAR_TYPE_POINT){
		var = var->var;
	}

	if(right_type == EXP_NODE_TYPE_CONST_INT){
		if(var->type == EXP_VAR_TYPE_STRUCT){
			exp_var_t *subvar = exp_var_struct_get_index(var,right_int);
			if(subvar == NULL){
				return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
			}

			result = exp_node_create(EXP_NODE_TYPE_VAR,NULL);
			result->var = exp_var_refer(subvar);
			return result;
		}else if(var->type == EXP_VAR_TYPE_ARRAY){
			exp_var_t *subvar = exp_var_array_get(var,right_int);
			if(subvar){
				result = exp_node_create(EXP_NODE_TYPE_VAR,NULL);
				result->var = exp_var_refer(subvar);
			}else{
				while(right_int >= var->array->len){
					exp_array_add(var->array,exp_var_create(NULL));
				}
				subvar = exp_var_array_get(var,right_int);
				if(subvar){
					result = exp_node_create(EXP_NODE_TYPE_VAR,NULL);
					result->var = exp_var_refer(subvar);
				}else{
					result = exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
				}
			}
			return result;
		}else if(var->type == EXP_VAR_TYPE_STRING){
			if(var->str && (int)strlen(var->str) > right_int && right_int >= 0){
				char buf[2] ={0};
				buf[0] = var->str[right_int];
				result = exp_node_create(EXP_NODE_TYPE_CONST_STRING,buf);
			}else{
				result = exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
			}
			return result;
		}else{
			return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
		}
	}else if(right_type == EXP_NODE_TYPE_CONST_STRING){
		if(var->type != EXP_VAR_TYPE_STRUCT){
			return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
		}
		return json_dot(left,right);
	}

	return NULL;
}

static exp_node_t *and(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	int left_flag = judge(left);
	int right_flag = judge(right);

	if(left_flag && right_flag){
		return exp_node_create(EXP_NODE_TYPE_CONST_TRUE,NULL);
	}else{
		return exp_node_create(EXP_NODE_TYPE_CONST_FALSE,NULL);
	}
}

static exp_node_t *or(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	int left_flag = judge(left);
	int right_flag = judge(right);

	if(left_flag || right_flag){
		return exp_node_create(EXP_NODE_TYPE_CONST_TRUE,NULL);
	}else{
		return exp_node_create(EXP_NODE_TYPE_CONST_FALSE,NULL);
	}
}

static exp_node_t *nor(exp_node_t *left, exp_node_t *right)
{
	if (right == NULL) {
		return NULL;
	}

	int right_flag = judge(right);

	if(!right_flag){
		return exp_node_create(EXP_NODE_TYPE_CONST_TRUE,NULL);
	}else{
		return exp_node_create(EXP_NODE_TYPE_CONST_FALSE,NULL);
	}
}

static exp_node_t *bitnor(exp_node_t *left, exp_node_t *right)
{
	if (right == NULL) {
		return NULL;
	}

	exp_node_type_e type;
	int num;

	get_exp_node_value(right,&type,NULL,&num,NULL);
	if(type != EXP_NODE_TYPE_CONST_INT){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	int ret = ~num;
	return exp_node_create(EXP_NODE_TYPE_CONST_INT,(void*)ret);
}

static exp_node_t *bitor(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type,right_type;
	int left_num,right_num;

	get_exp_node_value(right,&right_type,NULL,&right_num,NULL);
	get_exp_node_value(left,&left_type,NULL,&left_num,NULL);
	if(right_type != EXP_NODE_TYPE_CONST_INT || left_type != EXP_NODE_TYPE_CONST_INT){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	int ret = left_num | right_num;
	return exp_node_create(EXP_NODE_TYPE_CONST_INT,(void*)ret);
}

static exp_node_t *bitand(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type,right_type;
	int left_num,right_num;

	get_exp_node_value(right,&right_type,NULL,&right_num,NULL);
	get_exp_node_value(left,&left_type,NULL,&left_num,NULL);
	if(right_type != EXP_NODE_TYPE_CONST_INT || left_type != EXP_NODE_TYPE_CONST_INT){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	int ret = left_num & right_num;
	return exp_node_create(EXP_NODE_TYPE_CONST_INT,(void*)ret);
}

static exp_node_t *bitxor(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type,right_type;
	int left_num,right_num;

	get_exp_node_value(right,&right_type,NULL,&right_num,NULL);
	get_exp_node_value(left,&left_type,NULL,&left_num,NULL);
	if(right_type != EXP_NODE_TYPE_CONST_INT || left_type != EXP_NODE_TYPE_CONST_INT){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	int ret = left_num ^ right_num;
	return exp_node_create(EXP_NODE_TYPE_CONST_INT,(void*)ret);
}

static exp_node_t *left_shift(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type,right_type;
	int left_num,right_num;

	get_exp_node_value(right,&right_type,NULL,&right_num,NULL);
	get_exp_node_value(left,&left_type,NULL,&left_num,NULL);
	if(right_type != EXP_NODE_TYPE_CONST_INT || left_type != EXP_NODE_TYPE_CONST_INT){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	int ret = left_num << right_num;
	return exp_node_create(EXP_NODE_TYPE_CONST_INT,(void*)ret);
}

static exp_node_t *right_shift(exp_node_t *left, exp_node_t *right)
{
	if (left == NULL || right == NULL) {
		return NULL;
	}

	exp_node_type_e left_type,right_type;
	int left_num,right_num;

	get_exp_node_value(right,&right_type,NULL,&right_num,NULL);
	get_exp_node_value(left,&left_type,NULL,&left_num,NULL);
	if(right_type != EXP_NODE_TYPE_CONST_INT || left_type != EXP_NODE_TYPE_CONST_INT){
		return exp_node_create(EXP_NODE_TYPE_CONST_NULL,NULL);
	}

	int ret = left_num >> right_num;
	return exp_node_create(EXP_NODE_TYPE_CONST_INT,(void*)ret);
}

const static struct operator_t opers[] = {
	{OPERTOR_TYPE_AND,				13, "&&", and},
	{OPERTOR_TYPE_OR,				13, "||", or},
	{OPERTOR_TYPE_EVALUATION,		15, "=" , evaluation},
	{OPERTOR_TYPE_PLUSEVALUATION,	15, "+=", plus_evaluation},
	{OPERTOR_TYPE_SUBTEVALUATION,	15, "-=", sub_evaluation},
	{OPERTOR_TYPE_REFER,			15, "=>", refer},
	{OPERTOR_TYPE_BITOR,			11, "|" , bitor},
	{OPERTOR_TYPE_BITXOR,			10, "^" , bitxor},
	{OPERTOR_TYPE_BITAND,			9 , "&" , bitand},
	{OPERTOR_TYPE_EQUAL,			8 , "==", equal},
	{OPERTOR_TYPE_UNEQUAL,			8 , "!=", unequal},
	{OPERTOR_TYPE_GREATER,			8 , ">" , greater},
	{OPERTOR_TYPE_LESS,				8 , "<" , less},
	{OPERTOR_TYPE_GREATER_EQUAL,	8 , ">=", greater_equal},
	{OPERTOR_TYPE_LESS_EQUAL,		8 , "<=", less_equal},
	{OPERTOR_TYPE_LEFTSHIFT,		6 , "<<", left_shift},
	{OPERTOR_TYPE_RIGHTSHIFT,		6 , ">>", right_shift},
	{OPERTOR_TYPE_PLUS,				5 , "+" , plus},
	{OPERTOR_TYPE_SUBTRACTION,		5 , "-" , subtraction},
	{OPERTOR_TYPE_MULTIPLY,			4 , "*" , multiply},
	{OPERTOR_TYPE_DIVISION,			4 , "/" , division},
	{OPERTOR_TYPE_REMAINDER,		4 , "%" , remainder},
	{OPERTOR_TYPE_NOR,				3 , "!" , nor},
	{OPERTOR_TYPE_BITNOR,			3 , "~" , bitnor},
	{OPERTOR_TYPE_PARENTHESIS_L,	2 , "(" , NULL},
	{OPERTOR_TYPE_PARENTHESIS_R,	2 , ")" , NULL},
	{OPERTOR_TYPE_DOT,				0 , "." , json_dot},
	{OPERTOR_TYPE_COMMA,			5 , "," , NULL},
	{OPERTOR_TYPE_BRACKET_L,		1 , "[" , bracket},
	{OPERTOR_TYPE_BRACKET_R,		1 , "]" , NULL},
};

const operator_t *opertor_get(char *str)
{
	unsigned long i;
	for (i = 0; i < sizeof(opers)/sizeof(struct operator_t); i++) {
		if (strlen(str) == strlen(opers[i].oper) &&
			strncmp(str, opers[i].oper, strlen(opers[i].oper)) == 0)
		{
			return opers + i;
		}
	}
	SCRIPT_DEBUG_ERR("Opertor get fail: %s\n",str);
	return NULL;
}

